#ifndef _MATRIX4_H_
#define _MATRIX4_H_
#include <cmath>
#include <iostream>
#include <stdlib.h>

class Vector3{
	public:
		float x,y,z;
		Vector3(float x0,float y0,float z0);
		Vector3();
		void set(float x0,float y0,float z0);
		void set(Vector3 &a);
		void add(Vector3 &a);
		void add(Vector3 &a,Vector3 &b);
		void subtract(Vector3 &a);
		void subtract(Vector3 &a,Vector3 &b);
		void negate();
		void negate(Vector3 &a);
		void scale(float s);
		void scale(float s,Vector3 &a);
		float dot(Vector3 &a);
		void cross(Vector3 &a,Vector3 &b);
		float magnitude();
		float length();
		void normalize();
		Vector3 divide(Vector3 &a);
		float angleBetween(Vector3 &v1, Vector3 &v2);
		float get(char a);
		float* get();
		float operator[](int i);
		Vector3& operator+(Vector3 &c);
		Vector3& operator-(Vector3 &c);
		Vector3& operator*(Vector3 &c);
		Vector3& operator*(float c);
		Vector3& operator/(float c);
		void operator=(Vector3 &c);
//		void operator=(Vector3 c);
		void printVector();
		bool equals(Vector3* v);
		double distToPlane(Vector3 *x, Vector3 *p1, Vector3 *p2, Vector3 *p3);
};

class Vector4 {  
	public:
  		float x,y,z,q;
		Vector4();
		Vector4(Vector4* v);
		Vector4(float x0,float y0,float z0, float q0);
		Vector4(float &x0,float &y0,float &z0, float &q0);
		void set(float x0,float y0,float z0, float q0);
		void set(Vector4 b);
		void add(Vector4 &a);
		void add(Vector4 &a,Vector4 &b);
		void subtract(Vector4 &a);
		void subtract(Vector4 &a,Vector4 &b);
		void negate();
		void negate(Vector4 &a);
		void scale(float s);
		void scale(float s,Vector4 &a);
		float dot(Vector4 &a);
		float magnitude();
		void normalize();
		void dehomoginize();
		float get(char a);
		float* get();
		float operator[](const int i);
		Vector4& operator+(Vector4 &c);
		Vector4& operator-(Vector4 &c);
		void printVector();
};

class Matrix4{
  	public:
		float M[16];

		Matrix4();
		float* getPointer();
		void identity();
		void set(float *A);
		void set(int i, float v);
		float get(int i);
		float* get();
		void rotationX(float rot);
		void rotationY(float rot);
		void rotationZ(float rot);
		void rotationArbitrary(Vector3 a, float rot);
		void multiply(Matrix4 a);
		void multiply(float* a);
		Vector3 vector3Mul(Vector3 b);
		Vector4	vector4Mul(Vector4 b);
    void printMatrix();
    void translate(float a, float b, float c);
    void scaleNonUni(float x, float y, float z);
    void scaleUni(float s);
};

#endif
